package emulator.shell.GUI.symbols;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.swing.table.AbstractTableModel;

import emulator.assembler.SymbolTable;
import emulator.assembler.SymbolTableEntry;
import emulator.assembler.SymbolTableSource;
import emulator.hardware.HwWord;

@SuppressWarnings("serial")
public class SymbolTableModel extends AbstractTableModel 
{
	private static String[] columns = { "Address", "Label", "Remark", "Type", "Source" };
	private static String[] typeNames = { "", "Code", "Data", "Word", "Text", "Chip", "Empty" };
	List<SymbolTableEntry> symbols = new ArrayList<SymbolTableEntry>();
	
	@Override
	public String getColumnName(int column)
	{
		return columns[column];
	}

	@Override
	public int getRowCount()
	{
		return symbols.size();
	}

	@Override
	public int getColumnCount()
	{
		return columns.length;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex)
	{
		switch (columnIndex)
		{
		case 0: return "$" + new HwWord(symbols.get(rowIndex).getAddress());
		case 1: return symbols.get(rowIndex).getLabel();
		case 2: return symbols.get(rowIndex).getRemark();
		case 3: return typeNames[symbols.get(rowIndex).getType()];
		case 4: return symbols.get(rowIndex).getSource();
		}
		return null;
	}

	public void add(SymbolTableEntry entry)
	{
		symbols.add(entry);
	}

	public int getAddressAtSymbolLine(int rowIndex)
	{
		return symbols.get(rowIndex).getAddress();
	}

	public List<SymbolSourceModel> getSources(boolean selectUser) {
		Set<SymbolTableSource> sources = new LinkedHashSet<SymbolTableSource>();
		for (SymbolTableEntry entry : symbols)
		{
			sources.add(entry.getSource());
		}
		List<SymbolSourceModel> result = new ArrayList<SymbolSourceModel>();
		for (SymbolTableSource source : sources)
		{
			SymbolSourceModel sourceModel = new SymbolSourceModel();
			sourceModel.setSelected(selectUser && source == SymbolTable.userSymbol);
			sourceModel.setSource(source);
			sourceModel.setSourceName(source.getSourceName());
			result.add(sourceModel);
		}
		return result;
	}

}
